package com.xxx.ware.ware_manage_sys.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxx.ware.ware_manage_sys.bean.constant.MQTopicConst;
import com.xxx.ware.ware_manage_sys.bean.dto.GoodsQueryDto;
import com.xxx.ware.ware_manage_sys.bean.dto.GoodsSaveUpdateDto;
import com.xxx.ware.ware_manage_sys.bean.dto.OptRecordDto;
import com.xxx.ware.ware_manage_sys.bean.dto.WebResultDto;
import com.xxx.ware.ware_manage_sys.bean.entity.goods.WmsGoods;
import com.xxx.ware.ware_manage_sys.bean.entity.goods_cate.WmsGoodsCategory;
import com.xxx.ware.ware_manage_sys.bean.entity.user.WmsUser;
import com.xxx.ware.ware_manage_sys.bean.entity.warehouse.WmsWsDetail;
import com.xxx.ware.ware_manage_sys.bean.enums.OptModuleEnum;
import com.xxx.ware.ware_manage_sys.bean.event.Event;
import com.xxx.ware.ware_manage_sys.bean.event.EventProducter;
import com.xxx.ware.ware_manage_sys.bean.vo.GoodsVo;
import com.xxx.ware.ware_manage_sys.mapper.WmsGoodsMapper;
import com.xxx.ware.ware_manage_sys.mapper.WmsUserMapper;
import com.xxx.ware.ware_manage_sys.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class WmsGoodsServiceImpl extends ServiceImpl<WmsGoodsMapper, WmsGoods> implements IWmsGoodsService, MQTopicConst {

    @Autowired
    private IUserService userService;

    @Autowired
    private IWsDetailService wsDetailService;

    @Autowired
    private IWmsGoodsCategoryService wmsGoodsCategoryService;

    @Autowired
    private EventProducter eventProducter;

    @Override
    public Boolean saveGoods(GoodsSaveUpdateDto goodsSaveUpdateDto) throws Exception {
        String userAccount = goodsSaveUpdateDto.getUserAccount();
        String userName = goodsSaveUpdateDto.getUserName();
        String userPhone = goodsSaveUpdateDto.getUserPhone();
        String goodsName = goodsSaveUpdateDto.getGoodsName();
        String cateName = goodsSaveUpdateDto.getCateName();
        String warehouseName = goodsSaveUpdateDto.getWarehouseName();
        String remark = goodsSaveUpdateDto.getRemark();

        //校验用户、仓库、物品种类是否存在
        WmsUser wmsUser = userService.getUserBySoleKey(userAccount, userName, userPhone);
        if (wmsUser == null) {
            throw new Exception("此用户不存在，用户账号：" + userAccount +
                                            "，用户姓名：" + userName +
                                            "，用户联系方式：" + userPhone);
        }
        WmsWsDetail wmsWsDetail = wsDetailService.getWareBySoleKey(warehouseName);
        if (wmsWsDetail == null) {
            throw new Exception("此仓库不存在，当前仓库名称：" + warehouseName);
        }
        WmsGoodsCategory wmsGoodsCategory = wmsGoodsCategoryService.getGoodsCateBySoleKey(cateName);
        if (wmsGoodsCategory == null) {
            throw new Exception("不存在此物品种类，当前类别：" + cateName);
        }

        //添加操作记录
        OptRecordDto optRecordDto = new OptRecordDto();
        //判断物品是否存在
        WmsGoods goodsByKey = getGoodsByKey(goodsName, warehouseName, cateName);
        //物品存在，数量加1
        if (goodsByKey != null) {
            LambdaUpdateWrapper<WmsGoods> updateWrapper = Wrappers.lambdaUpdate();
            updateWrapper.eq(WmsGoods::getGoodsName, goodsName);
            updateWrapper.eq(WmsGoods::getWarehouseName, warehouseName);
            updateWrapper.eq(WmsGoods::getCateName, cateName);
            updateWrapper.set(WmsGoods::getGoodsNum, goodsByKey.getGoodsNum() + 1);
            update(updateWrapper);
            //操作id
            optRecordDto.setOptId(String.valueOf(goodsByKey.getId()));
            //操作内容
            optRecordDto.setOptContent("商品数量加1，商品名称：" + goodsName +
                    "，商品种类：" + cateName + "，仓库名称：" + warehouseName);
        } else { //不存在，直接添加
            WmsGoods wmsGoods = new WmsGoods();
            wmsGoods.setGoodsName(goodsName);
            wmsGoods.setWarehouseName(warehouseName);
            wmsGoods.setCateName(cateName);
            wmsGoods.setGoodsNum(1);
            //物品不存在 初始化为1
            wmsGoods.setRemark(remark);
            save(wmsGoods);
            //操作id
            optRecordDto.setOptId(String.valueOf(wmsGoods.getId()));
            //操作内容
            optRecordDto.setOptContent("商品新增，数量初始化1，商品名称：" + goodsName +
                    "，商品种类：" + cateName + "，仓库名称：" + warehouseName);
        }

        //操作类型
        optRecordDto.setOptModule(OptModuleEnum.GOODS.getKey());
        //添加当前登录的管理员账号
        optRecordDto.setOpterAccount("");
        //管理员姓名
        optRecordDto.setOpterName("");
        //管理员联系方式
        optRecordDto.setOpterPhone("");
        //用户账号
        optRecordDto.setApplyAccount(wmsUser.getUserAccount());
        //用户姓名
        optRecordDto.setApplyName(wmsUser.getUserName());
        //用户联系方式
        optRecordDto.setApplyPhone(wmsUser.getUserPhone());

        //消息队列异步处理
        Event event = new Event();
        event.setTopic(OPT_RECORD);
        event.setMsg(JSON.toJSONString(optRecordDto));
        eventProducter.sendKafkaMsg(event);
//        optRecordService.addOptRecord(optRecordDto);
        return true;
    }

    /**
     * 获取某个仓库、某个分类的物品
     * @param goodsName 物品名称
     * @param warehouseName 仓库名称
     * @param cateName 种类名称
     * @return
     */
    private WmsGoods getGoodsByKey(String goodsName, String warehouseName, String cateName){
        LambdaQueryWrapper<WmsGoods> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(WmsGoods::getGoodsName, goodsName);
        queryWrapper.eq(WmsGoods::getWarehouseName, warehouseName);
        queryWrapper.eq(WmsGoods::getCateName, cateName);
        return this.getBaseMapper().selectOne(queryWrapper);
    }

    @Override
    public WebResultDto<GoodsVo> getGoodsList(GoodsQueryDto goodsQueryDto) {
        Integer pageNo = goodsQueryDto.getPageNo();
        Integer pageSize = goodsQueryDto.getPageSize();
        String goodsName = goodsQueryDto.getGoodsName();
        String warehouseName = goodsQueryDto.getWarehouseName();
        String cateName = goodsQueryDto.getCateName();
        LambdaQueryWrapper<WmsGoods> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(StringUtils.isNotBlank(goodsName), WmsGoods::getGoodsName, goodsName);
        queryWrapper.eq(StringUtils.isNotBlank(cateName), WmsGoods::getCateName, cateName);
        queryWrapper.eq(StringUtils.isNotBlank(warehouseName), WmsGoods::getWarehouseName, warehouseName);
        queryWrapper.orderByDesc(WmsGoods::getCreateTime);
        IPage<WmsGoods> page = new Page<>(pageNo, pageSize);
        IPage<WmsGoods> resultPage = this.getBaseMapper().selectPage(page, queryWrapper);
        if (resultPage == null ||
            resultPage.getRecords() == null ||
            resultPage.getRecords().isEmpty()) {
            return WebResultDto.getDataList(pageNo, pageSize, 0L, null);
        }
        List<GoodsVo> resultList = resultPage.getRecords().stream().map(
                e -> {
                    GoodsVo goodsVo = new GoodsVo();
                    BeanUtils.copyProperties(e, goodsVo);
                    return goodsVo;
                }
        ).collect(Collectors.toList());
        return WebResultDto.getDataList(pageNo, pageSize, resultPage.getTotal(), resultList);
    }

    @Override
    public Boolean updateGoods(GoodsSaveUpdateDto goodsSaveUpdateDto) throws Exception {
        //当前的商品不能编辑成和已有商品一样
        String goodsName = goodsSaveUpdateDto.getGoodsName();
        String cateName = goodsSaveUpdateDto.getCateName();
        String warehouseName = goodsSaveUpdateDto.getWarehouseName();
        //判断物品是否存在
        WmsGoods goodsByKey = getGoodsByKey(goodsName, warehouseName, cateName);
        if (goodsByKey != null) {
            throw new Exception("当前仓库下，当前种类的商品不能重复，仓库名："
                                            + warehouseName + "，商品类别："
                                            + cateName + "，商品名称："
                                            + goodsName + "，请重新编辑");
        }
        LambdaUpdateWrapper<WmsGoods> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(WmsGoods::getId, goodsSaveUpdateDto.getId());
        updateWrapper.set(WmsGoods::getGoodsName, goodsSaveUpdateDto.getGoodsName());
        updateWrapper.set(WmsGoods::getCateName, goodsSaveUpdateDto.getCateName());
        updateWrapper.set(WmsGoods::getWarehouseName, goodsSaveUpdateDto.getWarehouseName());
        update(updateWrapper);
        //添加操作记录
        OptRecordDto optRecordDto = new OptRecordDto();
        //操作id
        optRecordDto.setOptId(String.valueOf(goodsSaveUpdateDto.getId()));
        //操作类型
        optRecordDto.setOptModule(OptModuleEnum.GOODS.getKey());
        //操作内容
        optRecordDto.setOptContent("商品信息更新，商品名称：" + goodsName +
                "，商品种类：" + cateName + "，仓库名称：" + warehouseName);
        //消息队列异步处理
        Event event = new Event();
        event.setTopic(OPT_RECORD);
        event.setMsg(JSON.toJSONString(optRecordDto));
        eventProducter.sendKafkaMsg(event);
//        optRecordService.addOptRecord(optRecordDto);
        return true;
    }
}
